package com.powergisol.gis.controller;

import com.powergisol.gis.entity.TabService;
import com.powergisol.gis.service.FallBackService;
import com.powergisol.gis.service.MondbDataService;
import com.powergisol.gis.service.TabDataService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.powergisol.gis.util.Result;
import com.powergisol.gis.vo.TabServiceVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.*;
import java.security.Principal;
import java.util.*;


/**
 * Date: 2019/7/9  10:15
 * Description:
 */
@RestController
@Api(description = "服务管理" ,value = "服务管理")
public class TabServiceController {
    private static Logger logger = LoggerFactory.getLogger(TabServiceController.class);

    @Autowired
    private TabDataService tabDataService;

    @Autowired
    private MondbDataService mondbDataService;
    @Autowired
    private FallBackService fallBackService;

    @PostMapping("tabServiceList")
    @ApiOperation(value = "服务列表", notes = "服务列表")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "name", value = "名称", defaultValue = "1", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "page", value = "页数", defaultValue = "1", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "limit", value = "条数", defaultValue = "10", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "currentUserId", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "currentUserName", value = "当前用户名（与用户id必传一个）", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "type", value = "数据类型(数据类型id)", defaultValue = "0", required = true, paramType = "query")
    })
    public Result tabServiceList(TabServiceVo vo, Principal p){
        Result result = new Result();
//        if(null == vo.getCurrentUserName() && null == vo.getCurrentUserId()){
//            return result.failure(-1,"currentUserId和currentUserName不能全为空");
//        }
        if(StringUtils.isEmpty(vo.getCurrentUserName())){
            vo.setCurrentUserName(p.getName());
        }

        String levelCode = tabDataService.selectLevelById(vo.getType());
        vo.setLevelCode(levelCode);
        PageHelper.startPage(vo.getPage(), vo.getLimit());
        PageInfo<TabServiceVo> pageInfo = new PageInfo<TabServiceVo>(tabDataService.tabServiceList(vo));
        result.setCount((int) pageInfo.getTotal());
        result.setData(pageInfo.getList());
        return result;
    }
    @PostMapping("releaseTabService")
    @ApiOperation(value = "发布服务", notes = "发布服务")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "currentUserId", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "currentUserName", value = "当前用户名（与用户id必传一个）", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "type", value = "数据类型(数据类型id)", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "dataPath", value = "数据路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "title", value = "服务标题", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "keyword", value = "关键字", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "description", value = "描述", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "serviceType", value = "数服务类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "changeType", value = "转换类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "zipUrl", value = "压缩文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "uuid", value = "uuid标识", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "fileUrl", value = "文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "styleUrl", value = "样式路径", defaultValue = "0", required = true, paramType = "query")
    })
    public Result releaseTabService(TabServiceVo vo,Principal p){
        if(StringUtils.isEmpty(vo.getCurrentUserName())){
            vo.setCurrentUserName(p.getName());
        }
        return tabDataService.releaseTabService(vo);
    }

    @PostMapping("updateTabService")
    @ApiOperation(value = "修改服务", notes = "修改服务")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "id", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "currentUserId", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "type", value = "数据类型(数据类型id)", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "dataPath", value = "数据路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "title", value = "服务标题", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "keyword", value = "关键字", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "description", value = "描述", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "serviceType", value = "数服务类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "changeType", value = "转换类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "imgUrl", value = "图片url", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "fileUrl", value = "文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "styleUrl", value = "样式路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "originUrl", value = "原始文件路径", defaultValue = "0", required = true, paramType = "query")
    })
    public Result updateTabService(TabService vo){
        return tabDataService.updateTabService(vo);
    }

    @PostMapping("updateUrlTabService")
    @ApiOperation(value = "修改文件地址", notes = "修改文件地址")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "fileUrl", value = "文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "originUrl", value = "原始文件路径", defaultValue = "0", required = true, paramType = "query")
    })
    public Result updateUrlTabService(TabServiceVo vo){
        return tabDataService.updateTabService(vo);
    }

    @PostMapping("getTabServiceByName")
    @ApiOperation(value = "获取服务详情", notes = "获取服务详情")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务id", defaultValue = "0", required = true, paramType = "query"),
    })
    public Result getTabServiceByName(String name){
        return tabDataService.getTabServiceByName(name);
    }

    @PostMapping("upTabServiceState")
    @ApiOperation(value = "修改服务状态", notes = "修改服务状态")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "state", value = "状态(0 待发布 1启用 2暂停使用 3不可用)", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "serviceCoordinate", value = "服务坐标系", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "encodingType", value = "编码", defaultValue = "0", required = true, paramType = "query")
    })
    public Result upTabServiceState(Integer state,String name,String serviceCoordinate,String encodingType){
        Result result = new Result();
        TabService tabService = tabDataService.getByName(name);
        logger.info("修改服务={} 的状态={}", name,state);
        //如果为shp且未选择样式且发布则需默认样式
        if(4 == tabService.getServiceType() && (null == tabService.getStyleUrl()||("").equals(tabService.getStyleUrl())) && 1 == state){
            logger.info("shp文件style赋值", name);
            String resultType = fallBackService.getLayerType(tabService.getFileUrl(),encodingType);
            if(null == resultType){
                return result.failure(-1,"发布服务失败，请重试");
            }
            tabDataService.upTabServiceStyleUrl(tabService,resultType);
        }
        result  = tabDataService.upTabServiceState(tabService,state, name, serviceCoordinate,encodingType);
        return result;
    }


    @PostMapping("delTabServiceById")
    @ApiOperation(value = "删除服务", notes = "删除服务")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "uuid", value = "uuid", defaultValue = "0", required = true, paramType = "query"),
    })
    public Result delTabServiceById(String uuid){
        //删除服务
        Result result =tabDataService.delTabServiceByUuid(uuid);
        //删除mongo数据库相应文件
        mondbDataService.delByUuid(uuid);
        return result;
    }

    @PostMapping(path ="getServiceType")

    @ApiOperation(value = "服务类型", notes = "服务类型")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "staticNum", value = "静态值", defaultValue = "0", required = true, paramType = "query")
    })
    public Result getServiceType(Integer staticNum){
        Result result = new Result();
        result.setData(tabDataService.getServiceType(staticNum));
        return result;
    }

    @PostMapping(path ="upDataPath")
    @ApiOperation(value = "修改数据存放路径", notes = "修改数据存放路径")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "staticNum", value = "静态值", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "filePath", value = "存放路径", defaultValue = "0", required = true, paramType = "query")
    })
    public Result upDataPath(Integer staticNum,String filePath){
        Result result = new Result();
        tabDataService.upDataPath(filePath,staticNum);
        return result;
    }

    @PostMapping(path ="isServiceNameDouble")
    @ApiOperation(value = "服务名称是否重复", notes = "服务名称是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query")
    })
    public Result isServiceNameDouble(String name){
        Result result = new Result();
        result.setData(tabDataService.getServiceNameNum(name));
        return result;

    }


    @PostMapping("getDataType")
    @ApiOperation(value = "数据类型", notes = "数据类型")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "currentUserId", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "currentUserName", value = "当前用户名（与用户id必传一个）", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "type", value = "服务类型(数据类型id)", defaultValue = "0", required = true, paramType = "query")
    })
    public Result getDataType(TabServiceVo vo,Principal p){
        Result result = new Result();
        if(StringUtils.isEmpty(vo.getCurrentUserName())){
            vo.setCurrentUserName(p.getName());
        }
        result.setData(tabDataService.getDataType(vo));
        return result;
    }
    @PostMapping("getDataPath")
    @ApiOperation(value = "获取数据路径", notes = "获取数据路径")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "dataPath", value = "路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "suffixName", value = "后缀名", defaultValue = "0", required = true, paramType = "query")
    })
    public Result getDataPath(String dataPath,String suffixName){
        Result result = new Result();
        List<Map<String,Object>> list = recursionFile(dataPath,suffixName);
        result.setData(list);
        return result;
    }

    @PostMapping("upServicePosition")
    @ApiOperation(value = "修改服务位置", notes = "修改服务位置")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "content", value = "内容", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "uuid", value = "uuid", defaultValue = "0", required = true, paramType = "query")
    })
    public Result upServicePosition(String content,String uuid){
        logger.info("修改服务位置={}",uuid);
        Result result = new Result();
        TabService tabService = tabDataService.getByUuid(uuid);
        String key = null;
        switch (tabService.getServiceType()){
            case 5://b3dm三维模型文件（*.json）
            case 8://lob三维模型文件（*.json）
                key = getUrl(tabService.getFileUrl());
                break;
            case 6://osgb三维模型文件（*.xml）
                key = tabService.getFileUrl().substring(tabService.getFileUrl().lastIndexOf(File.separator)+1,tabService.getFileUrl().length());
                break;
            default:
                break;
        }
        //修改盘中文件
        String fileUrl = tabService.getFileUrl();
        File file = new File(fileUrl);
        file.delete();
        try {
            OutputStream outFile = new FileOutputStream(fileUrl);
            outFile.write(content.getBytes());
            outFile.flush();
            outFile.close();
        } catch (Exception e) {
            e.printStackTrace();
            return result.failure(-1,"修改失败");
        }
        //修改数据库文件
        mondbDataService.upByMD5(uuid,key,content);
        return result;
    }

    private String getUrl(String url){
        url = url.replace("\\",File.separator);
        int index=url.lastIndexOf(File.separator);
        index=url.lastIndexOf(File.separator, index-1);
        return url.substring(index+1,url.length());
    }

    private List<Map<String,Object>> recursionFile(String dataPath,String suffixName){
        List<Map<String,Object>> mapList = new ArrayList<>();
        if(null == dataPath){
            mapList = getRoots(mapList);
        }else{
            mapList = recursionFile(mapList,dataPath,suffixName);
        }
        return mapList;
    }

    private List<Map<String,Object>> getRoots(List<Map<String,Object>> mapList){
        File[] rootsArrays = File.listRoots();
        for (File file:rootsArrays ) {
            if(file.exists()){
                Map<String,Object> map = new HashMap<>();
                map.put("lastModified",file.lastModified());
                map.put("name",file.getName());
                map.put("path",file.getPath());
                map.put("size",file.length());
                if (file.isDirectory()) {
                    map.put("type","folder");
                } else {
                    map.put("type","file");
                }
                mapList.add(map);
            }
        }
        return mapList;
    }
    private List<Map<String,Object>> recursionFile(List<Map<String,Object>> mapList,String dataPath,String suffixName){
        File file = new File(dataPath);
        if(!file.exists()){
            return mapList;
        }
        File[] files = file.listFiles();
        if(null == files){
            return mapList;
        }
        for (File file1 : files) {
            Map<String,Object> map = new HashMap<>();
            map.put("lastModified",file1.lastModified());
            map.put("name",file1.getName());
            map.put("path",file1.getPath());
            if (file1.isDirectory()) {
                map.put("type","folder");
                mapList.add(map);
            } else {
                String suffix = file1.getName().substring(file1.getName().lastIndexOf(".") + 1);
                map.put("size",file1.length());
                map.put("type","file");
                if(null != suffixName && suffix.contains(suffixName)){
                    mapList.add(map);
                }
            }
        }
        return mapList;
    }

    @PostMapping("remote/releaseTabService")
    @ApiOperation(value = "发布服务", notes = "发布服务")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "Integer", name = "currentUserId", value = "当前用户id", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "currentUserName", value = "当前用户名（与用户id必传一个）", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "type", value = "数据类型(数据类型id)", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "dataPath", value = "数据路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "title", value = "服务标题", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "keyword", value = "关键字", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "description", value = "描述", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "Integer", name = "serviceType", value = "数服务类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "changeType", value = "转换类型", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "zipUrl", value = "压缩文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "uuid", value = "uuid标识", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "fileUrl", value = "文件路径", defaultValue = "0", required = true, paramType = "query"),
            @ApiImplicitParam(dataType = "String", name = "styleUrl", value = "样式路径", defaultValue = "0", required = true, paramType = "query")
    })
    public Result remoteReleaseTabService(TabServiceVo vo){
        return tabDataService.releaseTabService(vo);
    }

    @PostMapping("remote/isServiceNameDouble")
    @ApiOperation(value = "服务名称是否重复", notes = "服务名称是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(dataType = "String", name = "name", value = "服务名称", defaultValue = "0", required = true, paramType = "query")
    })
    public Result remoteServiceNameDouble(String name){
        Result result = new Result();
        result.setData(tabDataService.getServiceNameNum(name));
        return result;

    }
}
